package comp.racer.ip;

import java.util.Vector;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

/**
 *
 * @author David Leite
 * @author Italo Aguiar
 */
public class JpaDao<E> implements Dao<E> {

    private static EntityManagerFactory emf;
    private Class<E> clazz;

    public JpaDao(Class<E> clazz) {
        this.clazz = clazz;
    }

    private EntityManager getEntityManager() {
        if (getEmf() == null) {
            setEmf(Persistence.createEntityManagerFactory("CompRacerServerPU"));
        }

        return getEmf().createEntityManager();
    }

    //  INSERINDO OBJETOS
    public void insert(E obj) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            obj = em.merge(obj);
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }
    }

    public void insertList(List<E> objList) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            for (E object : objList) {
                em.merge(object);
            }

            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }

    }

    public void insertVariableObjects(E... objetos) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            for (E object : objetos) {
                em.merge(object);
            }
            tx.commit();

        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }
    }

    //  DELETANDO OBJETOS
    public void delete(E obj) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();
            obj = em.merge(obj);
            em.remove(obj);
            tx.commit();

        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }

    }

    public void deleteList(List<E> objList) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();

        try {
            tx.begin();

            for (Object obj : objList) {
                obj = em.merge(obj);
                em.remove(obj);
            }

            tx.commit();

        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }
    }

    //  PESQUISANDO OBJETOS
    public List<E> findAll() {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();
        List<E> list = new Vector<E>();

        try {
            tx.begin();
            //Query q = em.createNamedQuery(clazz.getSimpleName() + ".findAll");
            String query = "select o from " + clazz.getSimpleName() + " o";
            Query q = em.createQuery(query);

            list = q.getResultList();

            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }

        return list;
    }

    public List<E> getObjectFromQuery(String query, Object... parametros) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();
        int position = 1;
        List<E> array = new Vector<E>();

        try {
            tx.begin();

            Query q = em.createQuery(query);

            for (Object parametro : parametros) {
                q.setParameter(position++, parametro);
            }

            tx.commit();
            array = q.getResultList();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }
        return array;
    }

    //  ATUALIZANDO OBJETOS
    public E update(E obj) {
        EntityManager em = getEntityManager();
        EntityTransaction tx = em.getTransaction();
        E e = null;

        try {
            tx.begin();
            e = em.merge(obj);
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }

        return e;
    }

    // getters e setters
    public static EntityManagerFactory getEmf() {
        return emf;
    }

    public static void setEmf(EntityManagerFactory emf) {
        JpaDao.emf = emf;
    }
}
